use strict;
use warnings;
use JSON;
use Data::Dumper;
use Math::Random::Zipf;


if (scalar @ARGV != 6)
{
	die ("Invalid number of arguments supplied, call as:\n
		perl make_config.pl num_clients num_frontends num_files storage_size static_frontend_count max_time");
}

sub distance {
	my ($p1, $p2) = @_;

	return int(sqrt((@$p1[0] - @$p2[0])**2 + (@$p1[1] - @$p2[1])**2));
}

sub get_location {
	my $max_axis = shift @_;
	return [int(rand($max_axis)), int(rand($max_axis))];
}

my ($num_clients, $num_servers, $num_files, $storage_size, $static_frontend_count, $max_time) = @ARGV;

my @files = ();
my %config = ();
my $json = JSON->new->allow_nonref;
my $max_axis = 100;
my $zipf = Math::Random::Zipf->new($num_files * 2, 1);


my $interval = 20;

%{$config{'PARAMS'}} = (
	'storageSize' => $storage_size,
	'fileCount' => $num_files,
	'uptimeCost' => 100,
	'lagCost' => 1,
	'blocksPerFile' => 5,
	'replicationCost' => 0,
	'storageSize' => $storage_size,
        'bandwidthMultiple' => 10,
        'messageWeight' => 0.2,
        'staticFrontEndCount' => $static_frontend_count,
        'blockConsumptionTime' => 5,
	'overloadThreshold' => 0.9,
	'lowLoadThreshold' => 0.2,
	'highLoadThreshold' => 0.7,
	'replicationHotness' => .5,
	'deletionHotness' => .1,
	'hotnessInterval' => $interval * 2,
);


foreach my $i (0 .. $num_files - 1)
{
	$files[$i]{'size'} = $config{'PARAMS'}{'blocksPerFile'};
	$files[$i]{'distribution'} = $zipf->rand();
}

for my $i (0 .. $num_servers - 1)
{
	%{$config{'FRONTENDS'}[$i]} = (
		'files' => [],
		'location' => get_location($max_axis),
		'distances' => [],
	);
}

for my $i (0 .. $num_servers - 1)
{
	for my $j (0 .. $num_servers - 1)
	{
		push @{$config{'FRONTENDS'}[$i]{'distances'}}, distance($config{'FRONTENDS'}[$i]{'location'}, $config{'FRONTENDS'}[$j]{'location'});
	}
}

for my $i (0 .. $num_clients - 1)
{
	for my $j (0 .. @{$config{'FRONTENDS'}} - 1)
	{
		push @{$config{'CLIENTS'}[$i]}, distance(get_location($max_axis), $config{'FRONTENDS'}[$j]{'location'});
	}
}

foreach my $i (0 .. @files - 1)
{
	my $server_id, my $remaining_size;
	do 
	{
		$server_id = int rand($num_servers);

		$remaining_size = $storage_size * $static_frontend_count;

		for my $j (0 .. @{$config{'FRONTENDS'}[$server_id]{'files'}} - 1)
		{
			$remaining_size -= $files[$config{'FRONTENDS'}[$server_id]{'files'}[$j]]{'size'};
		}
	}
	while ($remaining_size < $files[$i]{'size'});

	push @{$config{'FRONTENDS'}[$server_id]{'files'}}, $i;
}

foreach my $i (0 .. $max_time/$interval)
{
	for my $j (0 .. @files - 1)
	{
		for my $k (0 .. $files[$j]{'distribution'})
		{
			push @{$config{'REQUESTS'}}, [(int(rand($num_clients)), $j, $i * $interval + int(rand($interval)))];
		}
	}
}

print $json->encode(\%config);
